#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int N = 1 << 11;

long long dp[2][N];
int n, m;
int main()
{
    while (~scanf("%d %d", &m, &n) && (n + m))
    {
        if (m > n)
            swap(n, m);
        int now = 0;
        memset(dp[now], 0, sizeof dp[now]);
        dp[now][0] = 1;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                now ^= 1;
                memset(dp[now], 0, sizeof(dp[now]));
                for (int k = 0; k < (1 << m); k++)
                    if (dp[now ^ 1][k])
                    {
                        //vertical | dont
                        dp[now][k ^ (1 << j)] += dp[now ^ 1][k];
                        if (j && (k & (1 << (j - 1))) && !(k & (1 << j)))
                            // horizontal
                            dp[now][k ^ (1 << (j - 1))] += dp[now ^ 1][k];
                    }
            }
        }
        printf("%lld\n", dp[now][0]);
    }
}
// 只向上竖放，和向左横放
// f[i][j][k]
// 1 ~ j位为当前行状态，j ~ m 为上一行状态
// 使用f[i][j-1][k] 推断下一个状态(k2 -> x)
// 当前更新把第j位从上一行更新成当前行状态。
// |  0  |  0  | k2  | k3  | k4  |
// | k0  | k1  |  x  |     |     |
// 1 表示该处可以放   0 表示该处不能放

// Situation 1 : 
// k2 = 1 : 竖放, x = 0; 
// k2 = 0 : 不放,留给右侧， x = 1;
// dp[i][j][k ^ (1 << j)] += dp[i][j - 1][k]

// Situation 2 : 
// 横放 : j > 0, k1 = 1, k2 = 0
// j , k & (1 << (j - 1)), !(k & (1 << j))
// dp[i][j][k ^ (1 << (j - 1))] += dp[i][j - 1][k]; 
